package app.core.ar;

import com.gitee.feizns.quickstart.domain.Types;
import com.gitee.feizns.quickstart.mybatis.flex.jpa.AutoIdPojo;
import com.gitee.feizns.quickstart.mybatis.flex.jpa.SnowFlakeIdIdPojo;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.util.LambdaGetter;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

import javax.persistence.MappedSuperclass;
import java.util.Objects;

/**
 * active record
 * 按需要调整需要的的字段、
 * 使用雪花id可以使用{@link SnowFlakeIdIdPojo}
 * @author feizns
 * @since 2023/06/04
 */
@Getter
@Setter
@ToString
@Accessors(chain = true)
@MappedSuperclass
@TypeDefs(@TypeDef(name = Types.JSON, typeClass = JsonStringType.class))
public abstract class Ar<T extends Ar<T>> extends AutoIdPojo<T> {

//    /**
//     * 数据版本（乐观锁字段）
//     */
//    @JsonIgnore
//    @Comment("数据版本（乐观锁字段）")
//    @Column(version = true, comment = "数据版本（乐观锁字段）")
//    protected Integer version;
//
//    /**
//     * 逻辑删除字段（该字段不做展示）
//     */
//    @JsonIgnore
//    @Comment("逻辑删除字段（1=已删除、0=未删除）")
//    @Column(isLogicDelete = true, comment = "逻辑删除字段（1=已删除、0=未删除）")
//    @javax.persistence.Column(columnDefinition = "BIT DEFAULT 0", nullable = false)
//    protected Boolean deleted;

    /**
     * 是否已存在
     * @param uniqueColumn 唯一列
     * @param value 值
     * @return boolean
     */
    public Long selectId(LambdaGetter<T> uniqueColumn, Object value) {
        //查询唯一列对应值的id
        return QueryChain.of(this.getClass()).eq(uniqueColumn, value).select(keyColumnName).objAs(Long.class);
    }

    /**
     * 独特列值是否是允许更新
     * @param uniqueColumn 唯一列
     * @param value 值
     * @return boolean
     */
    public boolean uniqueColumnValueIsUpdatable(LambdaGetter<T> uniqueColumn, Object value) {
        @SuppressWarnings("unchecked")
        Object thisValue = uniqueColumn.get((T) this);
        if ( !Objects.equals(thisValue, value) ) {
            Long id1 = selectId(uniqueColumn, value);
            return !Objects.equals(id1, id);
        }
        return true;
    }

}
